package com.meida.module.arc.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.vo.JoinBean;
import com.meida.common.security.OpenHelper;
import com.meida.common.utils.ApiAssert;
import com.meida.module.arc.client.entity.ArcCategory;
import com.meida.module.arc.client.entity.ArcDestory;
import com.meida.module.arc.client.entity.ArcInfo;
import com.meida.module.arc.client.enums.ArcDestoryStatusEnum;
import com.meida.module.arc.client.enums.ArchiveEnumInteger;
import com.meida.module.arc.provider.mapper.ArcDestoryMapper;
import com.meida.module.arc.provider.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 档案销毁接口实现类
 *
 * @author flyme
 * @date 2022-01-11
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ArcDestoryServiceImpl extends BaseServiceImpl<ArcDestoryMapper, ArcDestory> implements ArcDestoryService {

    @Autowired
    private UserUnitService userUnitService;

    @Autowired
    private ArcCategoryService arcCategoryService;

    private ArcDestorySettingService arcDestorySettingService;

    @Autowired
    private ArcUseRemindService arcUseRemindService;

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, ArcDestory destory, EntityMap extra) {
        return ResultBody.ok();
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<ArcDestory> cq, ArcDestory destory, EntityMap requestMap) {
        ApiAssert.isNotEmpty("全宗id不能为空", destory);
        ApiAssert.isNotEmpty("全宗id不能为空", destory.getQzId());
        ApiAssert.isNotEmpty("状态不能为空", destory.getStatus());
        cq.eq("qzId");
        cq.eq("categoryId");
        cq.eq("status");
        cq.eq("originalCount");
        cq.like("arcNo", destory.getArcNo());
        cq.like("filingYear", destory.getFilingYear());
        cq.like("retention", destory.getRetention());
        cq.like("maintitle", destory.getMaintitle());
        cq.like("responsibleby", destory.getResponsibleby());
        cq.like("verifyUserName", destory.getVerifyUserName());
        cq.like("supervisorName", destory.getSupervisorName());
        cq.like("verifyTime", destory.getVerifyTime());
        cq.like("destoryTime", destory.getDestoryTime());
        cq.like("reason", destory.getReason());
        //过滤用户负责机构的数据
        List<Long> unitIds = userUnitService.getLoginUserUnitIds(destory.getQzId(), null);
        if (FlymeUtils.isNotEmpty(unitIds)) {
            cq.lambda().in(ArcDestory::getUnitId, unitIds);
        }
        cq.orderByDesc("destory.createTime");

        return ResultBody.ok();
    }

    /**
     * 加入销毁库
     *
     * @param arcInfoList
     * @return
     */
    @Override
    public ResultBody destoryArcInfos(List<ArcInfo> arcInfoList) {
        //判断档案是否已经销毁，如果已经销毁则不能再次销毁
        List<Long> arcInfoIds = arcInfoList.stream().map(item -> {
            return item.getArcInfoId();
        }).collect(Collectors.toList());
        CriteriaQuery<ArcDestory> destoryCriteriaQuery = new CriteriaQuery<ArcDestory>(ArcDestory.class);
        destoryCriteriaQuery.lambda().in(ArcDestory::getArcInfoId, arcInfoIds)
                .eq(ArcDestory::getStatus, ArcDestoryStatusEnum.ARC_STATUS_0.getCode());
        List<ArcDestory> list = this.list(destoryCriteriaQuery);
        Map<Long, ArcDestory> map = list.stream().collect(Collectors.toMap(ArcDestory::getArcInfoId, ArcDestory -> ArcDestory));
        arcInfoList.forEach(item -> {
            ArcDestory destory = map.get(item.getArcInfoId());
            if (FlymeUtils.isNotEmpty(destory)) {
                destory.setStatus(ArcDestoryStatusEnum.ARC_STATUS_1.getCode());
                destory.setQzId(item.getQzId());
                destory.setCategoryId(item.getCategoryId());
                destory.setArcInfoId(item.getArcInfoId());
                destory.setUnitId(item.getUnitId());
                destory.setArcNo(item.getArcNo());
                destory.setOriginalCount(item.getOriginalCount());
                destory.setFilingYear(item.getFilingYear());
                destory.setRetention(item.getRetention());
                destory.setMaintitle(item.getMaintitle());
                destory.setResponsibleby(item.getResponsibleby());
                destory.setStatus(ArcDestoryStatusEnum.ARC_STATUS_1.getCode());
                destory.setDestoryType(ArchiveEnumInteger.IS_FALSE.getCode());
                this.updateById(destory);
            } else {
                //校验销毁库是已存在改档案  直接将档案isDestory设置为true
                CriteriaQuery<ArcDestory> destoryCriteriaQuery1 = new CriteriaQuery<ArcDestory>(ArcDestory.class);
                destoryCriteriaQuery1.lambda().eq(ArcDestory::getArcInfoId, item.getArcInfoId());
                Long count = this.count(destoryCriteriaQuery1);
                if (count == null || count == 0) {
                    ArcDestory destory1 = new ArcDestory();
                    destory1.setQzId(item.getQzId());
                    destory1.setCategoryId(item.getCategoryId());
                    destory1.setArcInfoId(item.getArcInfoId());
                    destory1.setUnitId(item.getUnitId());
                    destory1.setArcNo(item.getArcNo());
                    destory1.setOriginalCount(item.getOriginalCount());
                    destory1.setFilingYear(item.getFilingYear());
                    destory1.setRetention(item.getRetention());
                    destory1.setMaintitle(item.getMaintitle());
                    destory1.setResponsibleby(item.getResponsibleby());
                    destory1.setStatus(ArcDestoryStatusEnum.ARC_STATUS_1.getCode());
                    destory1.setDestoryType(ArchiveEnumInteger.IS_FALSE.getCode());
                    this.save(destory1);
                }
            }
        });
        return null;
    }

    @Override
    public ResultBody destory(Map param) {
        Object destoryIds = param.get("destoryIds");
        Object reason = param.get("reason");
        ApiAssert.isNotEmpty("销毁库对象不能为空", destoryIds);
        List<Long> destoryIdArr = Arrays.asList(destoryIds.toString().split(",")).stream().map(item -> {
            return Long.parseLong(item);
        }).collect(Collectors.toList());
        LambdaQueryWrapper<ArcDestory> lambdaQueryWrapper = new LambdaQueryWrapper<ArcDestory>();
        lambdaQueryWrapper.in(ArcDestory::getDestoryId, destoryIdArr);
        List<ArcDestory> list = this.list(lambdaQueryWrapper);
        ApiAssert.isNotEmpty("销毁库对象不能为空", list);

        List<Long> ids = new ArrayList<>();
        list.forEach(item -> {
            if (!item.getStatus().equals(ArcDestoryStatusEnum.ARC_STATUS_1.getCode())) {
                ApiAssert.failure("只有待销毁文件库可以加入销毁");
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            LambdaUpdateWrapper<ArcDestory> lambdaDestoryUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaDestoryUpdateWrapper.eq(ArcDestory::getDestoryId, item.getDestoryId())
                    .set(ArcDestory::getStatus, ArcDestoryStatusEnum.ARC_STATUS_2.getCode())
                    .set(ArcDestory::getDestoryUserId, OpenHelper.getUserId())
                    .set(ArcDestory::getDestoryTime, sdf.format(new Date()))
                    .set(ArcDestory::getDestoryType, ArchiveEnumInteger.IS_FALSE.getCode());
            if (FlymeUtils.isNotEmpty(reason)) {
                lambdaDestoryUpdateWrapper.set(ArcDestory::getReason, reason.toString());
            }
            ids.add(item.getArcInfoId());
            this.update(lambdaDestoryUpdateWrapper);
        });
        //TODO 定时销毁
        //TODO 定时销毁原文后修改销毁记录数量

        //消息记录
        for (Long id : ids) {
            this.arcUseRemindService.createRemid(6, "提交了档案销毁申请", list.get(0).getQzId(), OpenHelper.getUserId(), null, id);
        }

        return ResultBody.ok();
    }

    @Override
    public ResultBody verify(Map param) {
        Object verifyType = param.get("verifyType");
        Object destoryIds = param.get("destoryIds");
        Object supervisorName = param.get("supervisorName");
        ApiAssert.isNotEmpty("审核类型不能为空", verifyType);
        ApiAssert.isNotEmpty("销毁库档案id不能为空", destoryIds);

        Integer verifyTypeInt = Integer.parseInt(verifyType.toString());
        if (verifyTypeInt != 1 && verifyTypeInt != 0) {
            ApiAssert.failure("审核类型只能为0或1");
        }


        List<Long> destoryIdList = Arrays.asList(destoryIds.toString().split(",")).stream().map(item -> {
            return Long.parseLong(item);
        }).collect(Collectors.toList());

        LambdaQueryWrapper<ArcDestory> lambdaQueryWrapper = new LambdaQueryWrapper<ArcDestory>();
        lambdaQueryWrapper.in(ArcDestory::getDestoryId, destoryIdList);
        List<ArcDestory> list = this.list(lambdaQueryWrapper);

        List<Long> ids = list.stream().map(ArcDestory::getArcInfoId).collect(Collectors.toList());

        LambdaUpdateWrapper<ArcDestory> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.in(ArcDestory::getDestoryId, destoryIdList)
                .set(ArcDestory::getVerifyUserId, OpenHelper.getUserId())
                .set(ArcDestory::getVerifyUserName, OpenHelper.getUser().getNickName());
        if (verifyTypeInt == 1) {
            ApiAssert.isNotEmpty("监管人不能为空", supervisorName);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            lambdaUpdateWrapper.set(ArcDestory::getStatus, ArcDestoryStatusEnum.ARC_STATUS_3.getCode())
                    .set(ArcDestory::getSupervisorName, supervisorName.toString())
                    .set(ArcDestory::getVerifyTime, sdf.format(new Date()));
            //查询自动销毁配置，生成自动销毁日期
            //消息记录
            for (Long id : ids) {
                this.arcUseRemindService.createRemid(6, "通过了你的档案销毁申请", list.get(0).getQzId(), null, OpenHelper.getUserId(), id);
            }
        } else {
            lambdaUpdateWrapper.set(ArcDestory::getStatus, ArcDestoryStatusEnum.ARC_STATUS_1.getCode());
            if (FlymeUtils.isNotEmpty(supervisorName)) {
                lambdaUpdateWrapper.set(ArcDestory::getSupervisorName, supervisorName.toString());
            }
            //消息记录
            for (Long id : ids) {
                this.arcUseRemindService.createRemid(6, "驳回了你的档案销毁申请", list.get(0).getQzId(), null, OpenHelper.getUserId(), id);
            }
        }
        this.update(lambdaUpdateWrapper);

        return ResultBody.ok();
    }

    @Override
    public ResultBody getDestoryCategory(Map param) {
        Object status = param.get("status");
        ApiAssert.isNotEmpty("销毁库类型不能为空", status);
        CriteriaQuery<ArcDestory> destoryCriteriaQuery = new CriteriaQuery<ArcDestory>(ArcDestory.class);
        JoinBean joinBean = destoryCriteriaQuery.createJoin(ArcCategory.class);
        joinBean.setMainField("categoryId");
        joinBean.setJoinField("categoryId");
        destoryCriteriaQuery.addSelect(ArcCategory.class, "categoryId", "cnName");
        destoryCriteriaQuery.eq(ArcDestory.class, "status", Integer.parseInt(status.toString()));
        List<String> groupByList = new ArrayList<String>();
        groupByList.add("category.categoryId");
        groupByList.add("category.cnName");
        destoryCriteriaQuery.groupBy(groupByList);
        return this.baseList(destoryCriteriaQuery);
    }

    @Override
    public void delCategory(Long categoryId) {
        CriteriaQuery<ArcDestory> fdQuery = new CriteriaQuery<>(ArcDestory.class);
        fdQuery.lambda().eq(ArcDestory::getCategoryId, categoryId);
        this.baseMapper.delete(fdQuery);
    }
}
